﻿using Frameworks;
using Network.Core.RPC;
using Network.Server;
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public enum LobbyEvent
{
    LoginSuccess,
}

public class LobbyManager : MonoBehaviour
{
    [Header("Model")]
    public GameObject model_page;
    public Button singleplayer_btn;
    public Button multiplayer_btn;

    [Header("Host")]
    public GameObject host_page;
    public GameObject roomInfo_template;
    public Button create_btn;
    public Button join_btn;
    public Button close_btn;

    private RoomDataEntity _selectedRoom;
    private List<RoomDataEntity> _roomList = new List<RoomDataEntity>();

    [Header("Room")]
    public GameObject room_page;
    public Text host_txt;
    public GameObject playerInfo_template;
    public Button ready_btn;
    public Button start_btn;

    private List<GameObject> _playerList = new List<GameObject>();

    private void Awake()
    {
        // Model
        singleplayer_btn.onClick.AddListener(singleplaye);
        multiplayer_btn.onClick.AddListener(multiplayer);

        // Host
        create_btn.onClick.AddListener(createServer);
        join_btn.onClick.AddListener(joinServer);
        //close_btn.onClick.AddListener(closeServer);

        // Room
        ready_btn.onClick.AddListener(ready);
        start_btn.onClick.AddListener(startGame);

        EventProxy.AddEventListener(LobbyEvent.LoginSuccess, LoginSuccess);
    }

    private void Start()
    {
        Network.Utils.Time.DateTimeAppStart = DateTime.Now;

        //initDebuger();

        model_page.SetActive(true);
        host_page.SetActive(false);
        room_page.SetActive(false);
        start_btn.gameObject.SetActive(false);

        EventProxy.AddEventListener(UdpBroadcastEvent.ReceiveRoomInfo, ReceiveRoomInfo);
    }

    private void Update()
    {
        updateRoomList();
    }

    private void OnDestroy()
    {
        // 停止广播/接收房间信息
        UdpBroadcast.Instance.StopBroadcast();
        UdpBroadcast.Instance.StopReceive();

        EventProxy.RemoveEventListener(UdpBroadcastEvent.ReceiveRoomInfo, ReceiveRoomInfo);

        // 注销RPC监听
        Client.OnlineManager.Instance.Net.Rpc.UnRegisterListener(this);

        if (UserManager.Instance.Room != null)
        {

        }

        EventProxy.RemoveEventListener(LobbyEvent.LoginSuccess, LoginSuccess);
    }

    private void initDebuger()
    {
        Network.Debugger.Debugger.Init(Application.streamingAssetsPath + "/ServerLog/", new Network.Debugger.UnityDebuggerConsole());
        Network.Debugger.Debugger.EnableLog = true;
        Network.Debugger.Debugger.EnableSave = true;
        Network.Debugger.Debugger.EnableLogVerbose = true;

        Network.Debugger.Debugger.Log();
    }

    #region Event
    private void ReceiveRoomInfo(EventData eventData)
    {
        if (eventData == null || eventData.target == null) return;

        RoomData roomData = eventData.target as RoomData;

        for (int i = 0; i < _roomList.Count; i++)
        {
            RoomDataEntity roomDataEntity = _roomList[i];

            if (roomDataEntity.roomData.port == roomData.port)
            {
                roomDataEntity.roomData = roomData;
                roomDataEntity.receivedTime = DateTime.Now.Ticks;
                return;
            }
        }

        RoomDataEntity roomDataEntityNew = new RoomDataEntity();
        roomDataEntityNew.roomData = roomData;
        roomDataEntityNew.receivedTime = DateTime.Now.Ticks;

        _roomList.Add(roomDataEntityNew);
    }
    #endregion

    #region Model
    private void singleplaye()
    {
        Debug.Log("还没写");

        Debug.Log(UserManager.Instance.IP);
        Debug.Log(UserManager.Instance.Port);
    }

    private void multiplayer()
    {
        // 显示网络相关UI
        model_page.SetActive(false);
        host_page.SetActive(true);

        // 开始接收房间信息
        UdpBroadcast.Instance.StartReceive();
    }
    #endregion

    #region Host
    private void createServer()
    {
        GameManager.Instance.AddFixedUpdateListener(ServerManager.Instance.Tick);

        // 登录模块
        Server.ZoneServer zoneServer = new Server.ZoneServer(ServerID.ZoneServer, UserManager.Instance.Port);
        ServerManager.Instance.StartServer(zoneServer);

        // 帧同步模块
        Server.GameServer gameServer = new Server.GameServer(ServerID.GameServer, 2939);
        ServerManager.Instance.StartServer(gameServer);

        Client.OnlineManager.Instance.IsHost = true;

        // Host直接登录
        login();
    }

    private void joinServer()
    {
        if (_selectedRoom == null) return;

        login();
    }

    private void closeServer()
    {
        ServerManager.Instance.StopAllServer();

        // 停止广播房间信息
        UdpBroadcast.Instance.StopBroadcast();
        // 开始接收房间信息
        UdpBroadcast.Instance.StartReceive();
    }

    private void exitServer()
    {

    }

    private void startGame()
    {
        Client.OnlineManager.Instance.Net.Rpc.Invoke("StartGame", Client.OnlineManager.Instance.MainUserData.id, UserManager.Instance.Room.id);
    }

    [RPCResponse]
    private void OnStartGame(GameServerStartParam param)
    {
        Debug.Log("创建游戏");
        Server.XJGameManager.Instance.CreateGame(param);
    }

    private void updateRoomList()
    {
        for (int i = 0; i < _roomList.Count; i++)
        {
            RoomDataEntity roomDataEntity = _roomList[i];

            if (roomDataEntity.toggle == null)
            {
                GameObject roomDataGo = Instantiate(roomInfo_template);
                roomDataGo.transform.SetParent(roomInfo_template.transform.parent);
                roomDataGo.gameObject.SetActive(true);
                Toggle toggle = roomDataGo.transform.GetComponent<Toggle>();
                Text label = roomDataGo.transform.Find("Label").GetComponent<Text>();

                roomDataEntity.toggle = toggle;
                roomDataEntity.label = label; roomDataEntity.label.text = string.Format("房间 [{0}] : {1}        [{2}/{3}]",
                    roomDataEntity.roomData.port, roomDataEntity.roomData.name, roomDataEntity.roomData.players.Count, roomDataEntity.roomData.maxPlayers);
                roomDataEntity.toggle.onValueChanged.AddListener(value =>
                {
                    if (value) { _selectedRoom = roomDataEntity; }
                });

                continue;
            }

            TimeSpan timeSpan = new TimeSpan(DateTime.Now.Ticks - roomDataEntity.receivedTime);
            if (timeSpan.Seconds > 3)
            {
                Destroy(roomDataEntity.toggle.gameObject);
                _roomList.Remove(roomDataEntity);
                break;
            }
        }
    }

    private void clearRoomList()
    {
        for (int i = 0; i < _roomList.Count; i++)
        {
            Destroy(_roomList[i].toggle.gameObject);
        }
        _roomList.Clear();
    }
    #endregion

    #region Client
    private void login()
    {
        string ip = "127.0.0.1";
        int port = 0;
        if (Client.OnlineManager.Instance.IsHost)
        {
            port = UserManager.Instance.Port;
        }
        else
        {
            ip = _selectedRoom.roomData.ip;
            port = _selectedRoom.roomData.port;
        }

        string account = SystemInfo.deviceName + "-" + UnityEngine.Random.Range(1000, 9999);
        Client.OnlineManager.Instance.Login(ip, port, account);
    }

    private void LoginSuccess(EventData eventData)
    {
        Client.OnlineManager.Instance.Net.Rpc.RegisterListener(this);

        if (Client.OnlineManager.Instance.IsHost)
        {
            Debug.Log("请求创建房间");
            Client.OnlineManager.Instance.Net.Rpc.Invoke("CreateRoom", Client.OnlineManager.Instance.MainUserData.id, "血战湘江");
        }
        else
        {
            Debug.Log("请求加入房间" + _selectedRoom.roomData.id);
            Client.OnlineManager.Instance.Net.Rpc.Invoke("JoinRoom", Client.OnlineManager.Instance.MainUserData.id, _selectedRoom.roomData.id);
        }
    }

    [RPCResponse]
    private void NotifyGameStart(XJGameStartParam param)
    {
        Debug.Log("游戏开始");

        room_page.SetActive(false);

        // 自动连接
        Client.XJGameManager.Instance.Start(param);

        // 自动开始
        Client.XJGameManager.Instance.GameBegin();
    }
    #endregion

    #region Room
    [RPCResponse]
    private void OnCreateRoom(RoomData roomData)
    {
        Debug.Log("创建房间成功,RoomID=" + roomData.id);

        // 加入房间
        Client.OnlineManager.Instance.Net.Rpc.Invoke("JoinRoom", Client.OnlineManager.Instance.MainUserData.id, roomData.id);

        // 开始广播房间信息
        UdpBroadcast.Instance.SetRoomInfo(roomData);
        UdpBroadcast.Instance.StartBroadcast();
        // 停止接收房间信息
        UdpBroadcast.Instance.StopReceive();
    }

    [RPCNotify]
    private void NotifyRoomUpdate(RoomData roomData)
    {
        Debug.Log("更新房间信息");

        UserManager.Instance.Room = roomData;

        // 显示房间相关UI
        host_page.SetActive(false);

        room_page.SetActive(true);
        host_txt.text = roomData.ip + ":" + roomData.port;

        updatePlayerList(roomData);

        for (int i = 0; i < roomData.players.Count; i++)
        {
            PlayerData playerData = roomData.players[i];
            if (playerData.userId == Client.OnlineManager.Instance.MainUserData.id)
            {
                UIUtils.SetButtonText(ready_btn, playerData.isReady ? "取消准备" : "开始准备");
                break;
            }
        }

        // 更新房间信息
        UdpBroadcast.Instance.SetRoomInfo(roomData);

        // 停止接收房间信息
        UdpBroadcast.Instance.StopReceive();
    }

    [RPCResponse]
    private void OnJoinRoomError(string message, int roomId)
    {
        Debug.Log("加入房间失败 RoomID=" + roomId + " " + message);
    }

    private void ready()
    {
        if (UIUtils.GetButtonText(ready_btn) == "开始准备")
        {
            Client.OnlineManager.Instance.Net.Rpc.Invoke("RoomReady", Client.OnlineManager.Instance.MainUserData.id, UserManager.Instance.Room.id, true);
        }
        else
        {
            Client.OnlineManager.Instance.Net.Rpc.Invoke("RoomReady", Client.OnlineManager.Instance.MainUserData.id, UserManager.Instance.Room.id, false);
        }
    }

    [RPCNotify]
    private void NotifyRoomIsAllReady(int roomId)
    {
        Debug.Log("玩家已经全部准备 RoomID=" + roomId);

        if (Client.OnlineManager.Instance.IsHost)
        {
            start_btn.gameObject.SetActive(true);
        }
    }

    [RPCNotify]
    private void NotifyRoomNotAllReady(int roomId)
    {
        Debug.Log("玩家没有全部准备 RoomID=" + roomId);

        if (Client.OnlineManager.Instance.IsHost)
        {
            start_btn.gameObject.SetActive(false);
        }
    }

    private void updatePlayerList(RoomData roomData)
    {
        clearPlayerList();

        for (int i = 0; i < roomData.players.Count; i++)
        {
            GameObject playerInfo = Instantiate(playerInfo_template);
            playerInfo.transform.SetParent(playerInfo_template.transform.parent);
            playerInfo.gameObject.SetActive(true);

            Image bg = playerInfo.transform.GetComponent<Image>();
            Text info = playerInfo.transform.Find("info").GetComponent<Text>();
            Transform ready = playerInfo.transform.Find("ready");

            PlayerData playerData = roomData.players[i];
            info.text = string.Format("[{0}] : {1}", playerData.id, playerData.name);
            ready.gameObject.SetActive(playerData.isReady);

            bg.color = playerData.userId == roomData.owner ? Color.green : Color.white;

            _playerList.Add(playerInfo.gameObject);
        }
    }

    private void clearPlayerList()
    {
        for (int i = 0; i < _playerList.Count; i++)
        {
            Destroy(_playerList[i]);
        }
        _playerList.Clear();
    }
    #endregion
}